﻿#include "MaterialDialogViscoElastic.h"
#include "ui_MaterialDialogViscoElastic.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsMaterialsViscoElastic.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include <QMessageBox>

namespace GUI
{
    MaterialDialogViscoElastic::MaterialDialogViscoElastic(PhysicsDlgExecType type, int matid /*= -1*/, QWidget* parent /*= nullptr*/)
        :AbstractMaterialDialog(type, parent)
    {
        _ui = new Ui::MaterialDialogViscoElastic;
        _ui->setupUi(this);
        //初始化频谱下拉列表
        Acoustics::FITKAcousticsPhysics* physics = Acoustics::FITKAcousticsPhysics::GetAcousticsPhysicsFromFrame();
        if (!physics)return;
        auto spectraManager = physics->getFITKAcousticsSpectraManager();
        if (!spectraManager)return;
        _ui->comboBox_DampingLossFactor->clear();
        _ui->comboBox_ShearModulus->clear();
        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraList1 = spectraManager->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::Damping);
        if (!spectraList1.isEmpty()) {
            for (auto spectra : spectraList1) {
                _ui->comboBox_DampingLossFactor->addItem(spectra->getDataObjectName(), spectra->getDataObjectID());
            }
        }
        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraList2 = spectraManager->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::ShearModulus);
        if (!spectraList2.isEmpty()) {
            for (auto spectra : spectraList2) {
                _ui->comboBox_ShearModulus->addItem(spectra->getDataObjectName(), spectra->getDataObjectID());
            }
        }
        //获取材料对象
        if (_matMgr && matid > 0)
            _mat = dynamic_cast<Acoustics::FITKAcousticsMaterialsViscoElastic*>(_matMgr->getDataByID(matid));
        this->init();

    }
    MaterialDialogViscoElastic::~MaterialDialogViscoElastic()
    {
        if (_ui) delete _ui;
    }
    void MaterialDialogViscoElastic::on_pushButtonOK_clicked()
    {
        if (!this->checkInput()) return;
        //要处理的对象
        Acoustics::FITKAcousticsMaterialsViscoElastic* visoE = dynamic_cast<Acoustics::FITKAcousticsMaterialsViscoElastic*>(_mat);
        //保存执行的脚本
        QStringList str;
        QString name = _ui->lineEdit_Name->text();
        //创建与复制,创建新对象
        if (_execType == GUI::PhysicsDlgExecType::Create || _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            str.append("m=Material.ViscoElasticSolids()");
            str.append(QString("m.createMaterial('%1')").arg(name));

            visoE = new Acoustics::FITKAcousticsMaterialsViscoElastic;
            _matMgr->appendDataObj(visoE);
        }
        if (!visoE)return;

        //保存数据
        double density = _ui->lineEdit_Density->text().toDouble();
        double poissonRatio = _ui->lineEdit_PoissonRatio->text().toDouble();
        QString nameG= _ui->comboBox_ShearModulus->currentText();
        QString nameDLF = _ui->comboBox_DampingLossFactor->currentText();

        if (_execType == GUI::PhysicsDlgExecType::Edit)
        {
            str.append(QString("m=Material.ViscoElasticSolids.GetViscoElasticSolids('%1')").arg(visoE->getDataObjectName()));
            str.append(QString("m.setName('%1')").arg(name));
        }
        str.append(QString("m.setDensityPoissonRatio(%1,%2)").arg(density).arg(poissonRatio));
        str.append(QString("m.setSpectra('%1','%2')").arg(nameG).arg(nameDLF));

        visoE->setDataObjectName(_ui->lineEdit_Name->text());
        visoE->setDensity(density);
        visoE->setPoissonsRatio(poissonRatio);

        int selectedIndex1 = _ui->comboBox_ShearModulus->currentIndex();
        QVariant dataIDVariant1 = _ui->comboBox_ShearModulus->itemData(selectedIndex1, Qt::UserRole);
        if (dataIDVariant1.isValid())
            visoE->setShearModulusSpectrumID(dataIDVariant1.toInt());

        int selectedIndex2 = _ui->comboBox_DampingLossFactor->currentIndex();
        QVariant dataIDVariant2 = _ui->comboBox_DampingLossFactor->itemData(selectedIndex2, Qt::UserRole);
        if (dataIDVariant2.isValid())
            visoE->setDampingSpectrumID(dataIDVariant2.toInt());

        this->saveScript(str);
        this->accept();
    }

    void MaterialDialogViscoElastic::on_pushButtonCancel_clicked()
    {
        this->reject();
    }

    void MaterialDialogViscoElastic::init()
    {
        if (_matMgr == nullptr) return;

        if (_execType == GUI::PhysicsDlgExecType::Create)
        {
            QString name = _matMgr->checkName("New Visco-Elastic Material");
            _ui->lineEdit_Name->setText(name);
        }

        Acoustics::FITKAcousticsMaterialsViscoElastic* visoE = dynamic_cast<Acoustics::FITKAcousticsMaterialsViscoElastic*>(_mat);
        if (!visoE)return;

        // 设置各个属性的值
        _ui->lineEdit_Name->setText(visoE->getDataObjectName());
        _ui->lineEdit_Density->setText(QString::number(visoE->getDensity()));
        _ui->lineEdit_PoissonRatio->setText(QString::number(visoE->getPoissonsRatio()));

        int shearID = visoE->getShearModulusSpectrumID();
        int index1 = _ui->comboBox_ShearModulus->findData(shearID);
        _ui->comboBox_ShearModulus->setCurrentIndex(index1);

        int specID = visoE->getDampingSpectrumID();
        int index2 = _ui->comboBox_DampingLossFactor->findData(specID);
        _ui->comboBox_DampingLossFactor->setCurrentIndex(index2);

        //复制,更新名称
        if (_execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            QString text = QString("Copy of %1").arg(visoE->getDataObjectName());
            _ui->lineEdit_Name->setText(text);
        }
    }

    bool MaterialDialogViscoElastic::checkInput()
    {
        //检查数据合法性
        QList<QLineEdit*> checkUi;
        checkUi << _ui->lineEdit_PoissonRatio << _ui->lineEdit_Density;
        for (QLineEdit* e : checkUi)
        {
            if (e == nullptr) continue;
            QString text = e->text().trimmed();
            bool ok = false;
            text.toDouble(&ok);
            if (!ok)
            {
                QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a number."));
                return false;
            }
        }
        if (_matMgr == nullptr) return false;
        //检查名称
        QString text = _ui->lineEdit_Name->text().trimmed();
        if (text != "") {
            QString newText = _matMgr->checkName(text);
            if (text == newText) return true;
            //与自己重名
            if (_matMgr->getDataByName(text) == _mat) return true;
        }

        QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a new Name."));
        return false;
    }
}